package com.example.zjx8969.myapplication.inject;

import android.app.Activity;
import android.view.View;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ViewInjectUtils {
    public static void injectEvents(Activity activity) {
        Class<? extends Activity> aClass = activity.getClass();
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            OnClick annotation = method.getAnnotation(OnClick.class);
            if (annotation == null) continue;
            Class<? extends Annotation> annotationType = annotation.annotationType();
            EventBase eventBase = annotationType.getAnnotation(EventBase.class);
            String listenerSetter = eventBase.listenerSetter();
            Class<?> listenerType = eventBase.listenerType();
            String methodName = eventBase.methodName();

            int[] viewIds = annotation.value();

            DynamicHandler dynamicHandler =new DynamicHandler(activity);
            dynamicHandler.addMethod(methodName, method);
            Object o = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class[]{listenerType}, dynamicHandler);

            for (int id : viewIds) {
                View view = activity.findViewById(id);
                try {
                    Method setEventMethod = view.getClass().getMethod(listenerSetter, listenerType);
                    setEventMethod.invoke(view,o);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void injectContentLayout(Activity activity) {
        Class<? extends Activity> aClass = activity.getClass();
        ContentView annotation = aClass.getAnnotation(ContentView.class);
        if (annotation == null) {
            throw new RuntimeException("contentView not set");
        }
        int layoutId = annotation.value();
        try {
            Method setContentView = aClass.getMethod("setContentView", int.class);
            setContentView.setAccessible(true);
            setContentView.invoke(activity, layoutId);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }


    public static void injectViews(Activity activity) {
        Class<? extends Activity> aClass = activity.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        Method findViewByIdMethod = null;
        for (Field field : declaredFields) {
            field.setAccessible(true);
            InjectView annotation = field.getAnnotation(InjectView.class);
            if (annotation == null) continue;
            int viewId = annotation.value();
            if (findViewByIdMethod == null) {
                try {
                    findViewByIdMethod = aClass.getMethod("findViewById", int.class);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }

            try {
                Object invoke = findViewByIdMethod.invoke(activity, viewId);
                field.set(activity, invoke);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

    }
}
